package com.example.redisDemo.effective_java;

import java.io.*;
import java.lang.reflect.InvocationTargetException;

public class Elvis implements Serializable {


    // 方式一：
    /*public static final Elvis INSTANCE = new Elvis();*/
    /*private Elvis(){
        if(INSTANCE !=null ){
            try {
                throw new Exception("防御");
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        System.out.println("调用了私有构造方法");
    }*/

    // 方式二：
    private static final Elvis INSTANCE = new Elvis();
    private Elvis() {}
    public static Elvis getInstance() {return INSTANCE;}

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, IOException, ClassNotFoundException {

        // 通过反射创建多个Singleton实例

        /*Elvis elvis1 = Elvis.INSTANCE;
        Elvis elvis2 = Elvis.INSTANCE;
        System.out.println(elvis1==elvis2);

        Constructor<Elvis> constructor = Elvis.class.getDeclaredConstructor();
        constructor.setAccessible(false); // 设置私有构造器的可访问性
        Elvis elvis3 = constructor.newInstance(); // 调用私有构造器创建对象
        System.out.println(elvis1==elvis3);*/

        Elvis elvis1 = Elvis.getInstance();

        // 创建 ByteArrayOutputStream 对象来序列化对象到字节数组
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(baos);
        // 将对象写入输出流
        out.writeObject(elvis1);
        // 关闭输出流
        out.close();
        byte[] serializedData = baos.toByteArray();

        // 创建 ByteArrayInputStream 对象来反序列化字节数组为对象
        ByteArrayInputStream bais = new ByteArrayInputStream(serializedData);
        ObjectInputStream in = new ObjectInputStream(bais);
        // 从输入流中读取对象
        Elvis elvis2 = (Elvis) in.readObject();
        // 关闭输入流
        in.close();

        System.out.println(elvis1==elvis2); // 输出false,说明通过反序列化创建出来的实例和之前的实例不同

    }
}
